package com.guigu.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.exam.entity.*;
import com.guigu.exam.exception.ExamException;
import com.guigu.exam.mapper.AnswerRecordMapper;
import com.guigu.exam.mapper.ExamRecordMapper;
import com.guigu.exam.mapper.PaperMapper;
import com.guigu.exam.mapper.QuestionMapper;
import com.guigu.exam.service.AnswerRecordService;
import com.guigu.exam.service.ExamRecordService;
import com.guigu.exam.service.KimiAiService;
import com.guigu.exam.vo.ExamRankingVO;
import com.guigu.exam.vo.StartExamVo;
import com.guigu.exam.vo.SubmitAnswerVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 考试记录Service实现类
 * 实现考试记录相关的业务逻辑
 */
@Service
public class ExamRecordServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamRecordService {
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private final QuestionMapper questionMapper;
    @Autowired
    private AnswerRecordMapper answerRecordMapper;
    @Autowired
    private AnswerRecordService answerRecordService;
    @Autowired
    private KimiAiService kimiAiService;

    public ExamRecordServiceImpl(PaperMapper paperMapper, QuestionMapper questionMapper) {
        this.paperMapper = paperMapper;
        this.questionMapper = questionMapper;
    }

    /**
     * 开始考试
     *
     * @param startExamVo
     * @return examRecord
     */
    @Override
    public ExamRecord startExam(StartExamVo startExamVo) {
        //先根据试卷id、考生姓名、考试记录状态查询考试记录
        ExamRecord examRecord = baseMapper.selectOne(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, startExamVo.getPaperId()).eq(ExamRecord::getStudentName, startExamVo.getStudentName()).eq(ExamRecord::getStatus, "进行中"));
        if (examRecord != null) {
            //该考生针对当前试卷已经存在考试记录，直接返回
            return examRecord;
        }
        examRecord = new ExamRecord();
        //设置属性值
        //设置试卷id
        examRecord.setExamId(startExamVo.getPaperId());
        //设置考生姓名
        examRecord.setStudentName(startExamVo.getStudentName());
        //设置考试开始时间
        examRecord.setStartTime(LocalDateTime.now());
        //设置窗口切换的次数
        examRecord.setWindowSwitches(0);
        //设置考试状态为进行中
        examRecord.setStatus("进行中");
        //调用Mapper层的方法插入考试记录
        baseMapper.insert(examRecord);
        return examRecord;
    }

    @Override
    public ExamRecord getExamRecordDetailsById(Integer id) {
        //调用BaseMapper中根据id查询考试详情的方法
        ExamRecord examRecord = baseMapper.selectById(id);
        //获取试卷的题目列表（题目中没有答案和选项）
        Paper paper = paperMapper.getDetailById(examRecord.getExamId());
        //获取试卷中题目的答案和选项
        //获取试卷中所有的题目
        List<Question> questions = paper.getQuestions();
        //遍历
        questions.forEach(question -> {
            //根据题目id包含答案和选项的题目
            Question questionContainsAswer = questionMapper.getQuestionDetailsById(question.getId());
            //设置题目选项
            question.setChoices(questionContainsAswer.getChoices());
            //设置题目答案
            question.setAnswer(questionContainsAswer.getAnswer());
        });
        //对题目进行排序：选择题在前、判断题在中间、简答题在最后
        questions.sort(((o1, o2) -> o1.getType().compareTo(o2.getType())));
        //设置试卷的题目列表
        examRecord.setPaper(paper);
        //获取考试记录的答题记录列表（供判卷和前端展示使用）
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));
        if (!CollectionUtils.isEmpty(answerRecords)) {
            //设置答题记录
            examRecord.setAnswerRecords(answerRecords);
        }
        return examRecord;
    }

    @Override
    public void submitAnswers(Integer examRecordId, List<SubmitAnswerVo> answers) {
        //1.根据考试记录id查询考试记录
        ExamRecord examRecord = baseMapper.selectById(examRecordId);
        //设置考试状态为已完成
examRecord.setStatus("已完成");
        //设置考试结束时间
        examRecord.setEndTime(LocalDateTime.now());
        //调用根据id更新的方法
        baseMapper.updateById(examRecord);
        //将List<SubmitAnswerVo> answers转换为List<AnswerRecord>类型
        List<AnswerRecord> answerRecordList = answers.stream().map(answer -> {
            AnswerRecord answerRecord = new AnswerRecord(examRecordId, answer.getQuestionId(), answer.getUserAnswer());
            return answerRecord;
        }).collect(Collectors.toList());
        //2.调用AnswerRecordService中的方法批量插入
        answerRecordService.saveBatch(answerRecordList);

        //3.调用判卷的方法
        gradePaper(examRecordId);
    }

    @Override
    public void removeExamRecordById(Integer id) {
        //根据id查询考试记录
        ExamRecord examRecord = baseMapper.selectById(id);
        //判断考试记录的状态
        if("进行中".equals(examRecord.getStatus())){
            //不能删除
            throw new ExamException(1010,"不能删除进行中的考试记录");
        }
        //删除考试记录
        baseMapper.deleteById(id);
        //删除答题记录
        answerRecordMapper.delete(new LambdaQueryWrapper<AnswerRecord>().eq(AnswerRecord::getExamRecordId, id));

    }

    @Override
    public List<ExamRankingVO> getExamRankingVOList(Integer paperId, Integer limit) {
        return baseMapper.getExamRankingVOList(paperId, limit);
    }

    /**
 * 判卷的方法
 *
 * @param examRecordId
 */
    private void gradePaper(Integer examRecordId) {
        //根据id查询考试记录详情
        ExamRecord examRecord = getExamRecordDetailsById(examRecordId);
        //获取答题记录
        List<AnswerRecord> answerRecords = examRecord.getAnswerRecords();
        //获取试卷中所有的问题
        List<Question> questions = examRecord.getPaper().getQuestions();
        //将 List<Question>转换为Map<Long,Question>类型
        Map<Long, Question> questionMap = questions.stream().collect(Collectors.toMap(Question::getId, question -> question));
        //遍历
        answerRecords.forEach(answerRecord -> {
            //获取答题记录中的问题的id
            Long questionId = answerRecord.getQuestionId();
            //根据问题的id获取问题
            Question question = questionMap.get(questionId);
            //判断是否是判断题
            if("JUDGE".equalsIgnoreCase(question.getType())){
                //将用户提交的T或F转换为true或false
                answerRecord.setUserAnswer(answerRecord.getUserAnswer().equalsIgnoreCase("T")?"TRUE":"FALSE");
            }
            //获取问题的正确答案
            String correctAnswer = question.getAnswer().getAnswer();
            //获取用户提交的答案
            String userAnswer = answerRecord.getUserAnswer();
            //判断是否是非简答题
            if(!"TEXT".equalsIgnoreCase(question.getType())){
                //判断用户提交的答案是否和正确答案一致
                if(correctAnswer.equalsIgnoreCase(userAnswer)){
                    //用户答案正确
                    //设置得分
                    answerRecord.setScore(question.getPaperScore().intValue());
                    //设置是否正确
                    answerRecord.setIsCorrect(1);
                }else{
                    //用户答案错误
                    //设置得分
                    answerRecord.setScore(0);
                    //设置是否正确
                    answerRecord.setIsCorrect(0);
                }
            }
            //调用AI处理简答题
            GradingResult gradingResult = kimiAiService.gradeTextQuestion(question, userAnswer);
            //设置简答题的得分
            answerRecord.setScore(gradingResult.getScore());
            //根据AI的判分结果设置是否正确（打满分才算正确）
            if(gradingResult.getScore() == question.getPaperScore().intValue()){
                //证明简答题得了满分
                answerRecord.setIsCorrect(1);
                //设置AI的反馈
                answerRecord.setAiCorrection(gradingResult.getFeedback());
            }else if(gradingResult.getScore() == 0){
                //一分没得
                answerRecord.setIsCorrect(0);
                answerRecord.setAiCorrection(gradingResult.getReason());
            }else{
                //部分得分
                answerRecord.setIsCorrect(2);
                answerRecord.setAiCorrection(gradingResult.getReason());
            }
            //更新答题记录
            answerRecordMapper.updateById(answerRecord);
        });
        //计算总得分
        Integer totalScore = answerRecords.stream().mapToInt(AnswerRecord::getScore).sum();
        //计算总的正确的答题数量
        Integer totalCorrectCount = answerRecords.stream().filter(answerRecord -> answerRecord.getIsCorrect() == 1).mapToInt(answerRecord -> 1).sum();
        //将本次考试的总得分设置到考试记录中
        examRecord.setScore(totalScore);
        //调用AI获取评语
        String summary = kimiAiService.getSummary(totalScore,examRecord.getPaper().getTotalScore().intValue(),examRecord.getPaper().getQuestionCount(),totalCorrectCount);
        //将本次考试的总评语设置到考试记录中
        examRecord.setAnswers(summary);
        //设置考试状态为已批阅
        examRecord.setStatus("已批阅");
        //更新考试记录
        baseMapper.updateById(examRecord);
    }
}